#ifndef _HAL_H
#define _HAL_H


/* Timer cfg */
#define HAL_AFE_TIMER_INT_ENABLE     0x1
#define HAL_AFE_TIMER_INT_DISABLE    0x0
#define HAL_AFE_TIMER_1_SHOT         0x2


/* HAL status */
typedef enum
{
	HAL_STAT_SUCCESS = 0,     // HAL success
	HAL_STAT_FAILURE = 1      // HAL failure
}HAL_status_t;

/* Callback functions */
typedef void (*HAL_cbFunc_t)(UINT32);

/* AFE Profile */
typedef struct
{
	UINT16 rx_fs_kHz;
	UINT16 tx_fs_kHz;
	UINT16 tx_pwm_kHz;
	UINT16 band;         //0-A; 1-FCC; 2-FCC_ARIB;
}HAL_afe_prfParms_t;

typedef struct
{
	UINT32 zcaTime;
	UINT16 zcaPeriod;
	UINT32 zcbTime;
}HAL_afe_zcTime_t;

/* RX Buffer Data Pointer & size, the previous just completed */
typedef struct
{
  UINT16 *buf_p;
  UINT32 size;
}HAL_afe_rxBufPtrSz_t;

/* AFE EPWM handle */
typedef struct
{
	Uint16          mepx2;                 // MEP scale factor (2x due to symmetric PWM)
	Uint16          prd;                   // EPWM period
	Uint16          socPrd;                // SOC period (RX)
	Uint16          txPrd;                 // TX period
}HAL_afe_epwm_handle_t;

typedef struct
{
	Uint16 txSize;                // 0 TX size
	Uint16 txActive;              // 1 TX active flag

	Uint16 updateGainFlag;     // 2 AGC gain update flag
	int16  agcGainVal;         // 3 AGC gain value

	/* Added for ADC int */
	volatile Uint16 *rxBufPtr_p[2];   // 4 5 6 7 RX buffer address (ping-pong buffer)
	volatile Uint16 *rxBufDat_p;      // 8 9

	Uint16 rxBufSize[2];              // 10 11 RX buffer size (Number of bursts in a transfer - 1)
	Uint16 rxBufIdx;                  // 12 RX buffer buffer index (next active buffer being filled)
	Uint16 adcCnt;                    // 13
	Uint16 rxBufCnt;                  // 14
	Uint16 adcIntCnt;                 // 15
	Uint16 activeBufIdx;           // 16 Active buffer index. Reload rxBufIdx @symbol done
	Uint16 activeBufSize;          // 17 Active buffer size. Reload rxBufSize[activeBufIdx] @symbol done

	/* For TX Buffers */
	volatile Uint16 *txBufReady_p;     // 18 19 TX buffer ready to be read
	volatile Uint16 *bufDat_p;         // 20 21 TX active buffer pointer
  
	Uint16 txBufIdx;                   // 22
	Uint16 txIntCnt;                   // 23
	Uint16 txBufSize;                  // 24

	UINT16 timer01ShotFlag;    //  25 Timer 0 cfg flags
	HAL_cbFunc_t cb_p;
	UINT32 cb_param;
	Uint32 rxDmaTime;          // RX DMA time (in 10us)

	Uint32 zcaTime;             // Zero-crossing time (in 10us)
	Uint32 zcaLatency;          // Zero-crossing latency (in CPU ticks)
	Uint32 zcaCap1;             // Zero-crossing captured (in CPU ticks)
	Uint32 zcbTime;             // Zero-crossing time (in 10us)
	Uint32 zcbLatency;          // Zero-crossing latency (in CPU ticks)
	Uint32 zcbCap1;             // Zero-crossing captured (in CPU ticks)

	HAL_afe_prfParms_t prf;

	Uint32 t0Prd;               // T0 period in us (Q1)
	
	SINT16 *rxBufDatPrvFld_p;      // The location of rxBudDat_p after previous buffer filled
	UINT16 rxBufSizePrvFld;

	UINT16 txPgaAttn;
	Uint16 zcaPeriod;           // half-cycle period (in 10us)
}HAL_afe_handle_t;

/* HAL_AFE set code */
typedef enum
{
	AFE_TX_CFG     = 0,        // TX configure
	AFE_TX_START   = 1,        // TX start
	AFE_TX_STOP    = 2,        // TX stop
	AFE_TX_RECFG   = 3,        // Reconfigure TX
	AFE_TX_DMASIZE = 4,        // Set TX DMA size
	AFE_TX_DMAADDR = 5,        // Set TX DMA address
	AFE_TX_T0CFG   = 6,        // Configure CPU timer 0
	AFE_TX_T0START = 7,        // Start CPU timer 0
	AFE_TX_T0STOP  = 8,        // Stop CPU timer 0

	AFE_RX_START   = 9,        // RX start
	AFE_RX_STOP    = 10,       // RX stop
	AFE_RX_RECFG   = 11,       // RX reconfigure
	AFE_RX_SETGAIN = 12,       // Set AGC gain
	AFE_RX_UPDATEGAIN = 13,    // Update AGC gain
	AFE_RX_CANCEL_GAIN = 14,   // Cancel gain update

	NUM_AFE_SETPARMS = 15
}HAL_afe_setCode_t;


/* AFE TX set parameters */
typedef struct
{
  SINT16 *txBuf_p;            // Pointer to the TX buffer
  UINT16 txSize;             // Size of TX buffer
  UINT32 t0PrdInUs;          // CPU timer 0 period (in us)
  UINT16 t0Flags;            // bit 0: CPU timer 0 interrupt enabled (1) or disabled (1)
                             // bit 1: 1 shot = 1, 0 = continuous
                             // This is enabled for txTime timeout, but disabled for TX DMA
  HAL_cbFunc_t cb_p;
  UINT32 cb_param;
}HAL_afe_txSetParms_t;

/* HAL_AFE get code */
typedef enum
{
  AFE_RX_DMATIME   = 0,        // RX DMA time
  AFE_ZCTIME       = 1,        // ZC time
  AFE_RX_DMAIDX    = 2,        // RX DMA index
  AFE_RND_NUM      = 3,        // random number generator
  AFE_RX_BUFPTR_SZ = 4,
  NUM_AFE_GETPARMS = 5
}HAL_afe_getCode_t;

/* AFE RX set parameters */
typedef struct
{
  UINT16 size[2];            // Sizes of RX ping-pong buffers
  UINT16 *dstBufAddr[2];     // DMA desination ping-pong buffer addresses
  UINT16 dstBufIdx;          // Destination buffer index. Always point to the readable buffer
}HAL_afe_rxSetParms_t;


extern HAL_afe_txSetParms_t HAL_afe_txSetParms_s;

HAL_status_t HAL_afeInit(HAL_afe_prfParms_t *setParms_p);
HAL_status_t HAL_afe_txCfg(void *setParms_s);
HAL_status_t HAL_afe_txReCfg(void *setParms_s);
HAL_status_t HAL_afe_txStart(void *setParms_p);
HAL_status_t HAL_afe_txStop(void *setParms_p);
HAL_status_t HAL_afe_txDmaSize(void *setParms);
HAL_status_t HAL_afe_txDmaAddr(void *setParms);
HAL_status_t HAL_afe_setGain(void *setParms_p);
HAL_status_t HAL_afe_updateGain(void *setParms_p);
HAL_status_t HAL_afe_cancelGain(void *setParms_p);
HAL_status_t HAL_cpuTimerCfg();
HAL_status_t HAL_cpuTimer1CfgStart();
Uint32 HAL_cpuTimer1GetCount(void);
HAL_status_t HAL_cpuTimer0TimeoutCfg(void *setParms);
HAL_status_t HAL_cpuTimer0Start(void *getParms);
HAL_status_t HAL_cpuTimer0Stop(void *getParms);
HAL_status_t HAL_afe_rxDmaTime(void *getParms);
HAL_status_t HAL_afe_zcTime(void *getParms);
HAL_status_t HAL_afe_rxDmaIdx(void *getParms);
HAL_status_t HAL_afe_rndNum(void *getParms);
HAL_status_t HAL_afe_rxBufPtrSz(void *getParms);
HAL_status_t HAL_afe_prfCfg(void *setParms_p);
HAL_status_t HAL_afe_rxStart(void *setParms_p);
HAL_status_t HAL_afeSet(HAL_afe_setCode_t setCode, void *setParms_p);
HAL_status_t HAL_afe_rxStop(void *setParms_p);
HAL_status_t HAL_afe_rxReCfg(void *setParms_p);
HAL_status_t HAL_afeGet(HAL_afe_getCode_t getCode, void *getParms_p);
void  HAL_cfgCpuTimer0(UINT16 cpu_frez_MHz, UINT16 fs_kHz);

void PLC_print(char *fmt, ...);

#endif //_HAL_H